﻿(function ($) {
    var ui = {};

    var Resource = function (resource) { return Carbon.Web.Forms.jQueryForms.Resources[resource]; };
    var ErrorStrings = {
        FormatException: function () { return Resource("Error.FormatException"); },
        MaxLengthExceeded: function (maxLength) { return Resource("Error.MaxLengthExceeded").replace("{0}", maxLength); }
    };

    PopupResources = function (val) {
        return Resource("Popup." + val);
    };

    var outerDivClass = "carbon-box";
    var errorClass = "carbon-error";

    var validationFailedClass = "carbon-validation-error";

    var carbonInputClass = "carbon-input";
    var carbonHoverClass = "carbon-input-hover";
    var carbonFocusClass = "carbon-input-focus";

    var carbonNumberClass = "carbon-number";

    var carbonDropDownClass = "carbon-dropdown";

    var removeElementFromArray = function (array, elem) {
        return $.grep(array, function (e) {
            return e !== elem;
        });
    };

    var Effects = {
        Show: function (element) {
            if ($.browser.msie) {
                element.show();
            }
            else {
                element.fadeIn();
            }
        },
        Hide: function (element) {
            if ($.browser.msie) {
                element.hide();
            }
            else {
                element.fadeOut();
            }
        }
    };

    var findSingle = function (context, selector) {
        var result = context.find(selector);

        if (result.length != 1) {
            throw "Element '" + selector + "' not found.";
        }

        return result;
    };

    var createEditor = function (clientId) {
        var $element = $("#" + clientId);
        var $box = $element.parent();
        var $error = $box.find("." + errorClass);
        var serverErrorText = $error.html();

        var editor = {
            Element: $element,
            OuterBox: $box,
            Error : $error,
            ShowingServerError: false,
            ServerError: serverErrorText,
        };

        editor.ShowValidationMessage = function (message) {
            this.Error.html(message);
            this.OuterBox.addClass(validationFailedClass);
            if (message)
                this.Error.show();
            else 
                this.Error.hide();
        };

        editor.ShowServerError = function () {
            if ($error.is(":visible")) {
                editor.ShowingServerError = true;
            }
        };

        editor.HideValidationMessage = function () {
            this.ShowingServerError = false;
            this.OuterBox.removeClass(validationFailedClass);
            this.Error.hide();
        };

        return editor;
    };

    ui.TextEditor = function (clientId, canbenull, regex, regexMessage, maxLength) {
        var editor = createEditor(clientId);

        var textBox = editor.Element;

        editor.ValidationExpression = regex;
        editor.CompiledExpression = null;

        if (regex) {
            editor.CompiledExpression = new RegExp(regex);
            if (!regexMessage)
                throw "Regex message not defined";
        }

        var lastValue = textBox.val();

        var changeHandlerSync = Function.createDelegate(textBox, function () {

            if (lastValue != textBox.val())
                editor.HideValidationMessage();

            var val = this.val();

            if (!editor.ShowingServerError) {
                var isValid = true;

                var message = null;

                if (!canbenull) {
                    if (val == "") {
                        isValid = false;
                        message = null;
                    }
                }

                if (editor.CompiledExpression != null && isValid && val !== "") {
                    if (!editor.CompiledExpression.test(val)) {
                        isValid = false;
                        message = regexMessage;
                    }
                }

                if (maxLength) {
                    if (val.length > maxLength) {
                        isValid = false;
                        message = ErrorStrings.MaxLengthExceeded(maxLength);
                    }
                }

                if (isValid) {
                    editor.HideValidationMessage();
                }
                else {
                    editor.ShowValidationMessage(message);
                }
            }

            lastValue = val;
        });

        var changeHandler = function () {
            setTimeout(changeHandlerSync, 0);
        };

        textBox.addClass(carbonInputClass);

        textBox.keyup(changeHandler);
        textBox.keydown(changeHandler);
        textBox.change(changeHandler);

        textBox.focus(function () {
            changeHandler();
            editor.OuterBox.addClass(carbonFocusClass);
        });

        textBox.blur(function () {
            changeHandler();
            editor.OuterBox.removeClass(carbonFocusClass);
        });

        textBox.mouseover(function () {
            editor.OuterBox.addClass(carbonHoverClass);
        });

        textBox.mouseout(function () {
            editor.OuterBox.removeClass(carbonHoverClass);
        });

        changeHandler();

        editor.ShowServerError();

        return editor;
    };

    ui.DateTimeEditor = function (clientId, canbenull, showDate, showTime) {
        var textEditor = ui.TextEditor(clientId, canbenull, null, null, null);

        if (!showDate && showTime)
            textEditor.Element.timepicker({});
        else if (showDate && !showTime)
            textEditor.Element.datepicker({});
        else if (showDate && showTime)
            textEditor.Element.datetimepicker({});
        else
            throw "Invalid date time picker";

        return textEditor;
    };

    ui.NumberEditor = function (clientId, canbenull, showDate, showTime) {
        var textEditor = ui.TextEditor(clientId, canbenull, null, null, null);
        textEditor.OuterBox.addClass(carbonNumberClass);

        textEditor.Element.css("text-align: right;");
        return textEditor;
    };

    ui.DropDown = function (clientId, canbenull) {
        var editor = createEditor(clientId);

        var dropDown = editor.Element;

        var changeHandlerSync = Function.createDelegate(dropDown, function () {
            if (!canbenull) {
                if (editor.Element.val() === "") {
                    editor.ShowValidationMessage();
                }
                else {
                    editor.HideValidationMessage();
                }
            }
        });

        var changeHandler = function () {
            setTimeout(changeHandlerSync, 0);
        };

        dropDown.addClass(carbonDropDownClass);

        dropDown.keyup(changeHandler);
        dropDown.keydown(changeHandler);
        dropDown.change(changeHandler);

        dropDown.focus(function () {
            editor.OuterBox.addClass(carbonFocusClass);
        });

        dropDown.blur(function () {
            editor.OuterBox.removeClass(carbonFocusClass);
        });

        dropDown.mouseover(function () {
            editor.OuterBox.addClass(carbonHoverClass);
        });

        dropDown.mouseout(function () {
            editor.OuterBox.removeClass(carbonHoverClass);
        });

        changeHandler();

        editor.ShowServerError();

        return dropDown;
    };

    ui.FileUploadEditor = function (clientId) {
        var editor = createEditor(clientId);

        var element = editor.Element;

        editor.add = element.find(".carbon-add-button");

        editor.add.hover(function () {
            $(this).addClass("ui-state-hover");
        },
        function () {
            $(this).removeClass("ui-state-hover");
        });

        element.find(".carbon-remove-button").hover(function () {
            $(this).addClass("ui-state-hover");
        },
        function () {
            $(this).removeClass("ui-state-hover");
        });

        editor.ShowServerError();

        return editor;
    };

    ui.GetRootPopupManager = function () {
        var root = window;
        while (root.parent && root.parent != root) {
            root = root.parent;
        }

        return root.PopupManagerInstance;
    };

    var PopupManager = function () {
        var allIframes = [];

        if (typeof (PopupManagerInstance) != "undefined") {
            throw "Only one popup manager can exist.";
        }

        var manager = {};
        
        var popup = null;

        manager.OpenPopup = function (args) {
            // URL is mandatory.
            if (args.Url == null)
                throw "Url is mandatory.";

            if (args.InvokeViewModelChanged == null)
                throw new "InvokeViewModelChanged function cannot be null.";

            // Set default values. $.dialog() has its own default values, but these the defaults for our application.
            var defaultValues = {
                Title: '&nbsp;',
                IsModal: true,
                IsResizable: true,
                IsDraggable: true,
                Height: 300,
                Width: 500,
                Class: 'carbon-dialog-fullscreen'
            };

            // Assign default values if none are passed in.
            var _title = args.Title || defaultValues.Title;
            var _width = args.Width || defaultValues.Width;
            var _height = args.Height || defaultValues.Height;
            var _isModal = (args.IsModal != null) ? args.IsModal : defaultValues.IsModal;
            var _isResizeable = (args.IsResizable != null) ? args.IsResizable : defaultValues.IsResizable;
            var _isDraggable = (args.IsDraggable != null) ? args.IsDraggable : defaultValues.IsDraggable;
            var _class = args.Class || defaultValues.Class;

            var jqui = Carbon.Web.Forms.jQueryForms;

            var loaderUrl = jqui.Configuration.FilesPath + '/' + jqui.Resources["Url.Loader"];

            var content = 
            '<div style="width:' + _width + 'px; height:' + _height + 'px; position:relative;">'
            + '<table class="carbon-loader-overlay" cellpadding="0" cellspacing="0" style="position:absolute; top:0px; left:0px; width:' + _width + 'px; height: ' + _height + 'px;"><tr><td style="vertical-align:middle; text-align:center">'
            + '<img border="0" src="' + loaderUrl + '" alt="" />'
            + '</td></tr></table>'
            + '<iframe width="' + _width + '" height="' + _height + '" frameborder="0" scrolling="auto" marginheight="0" marginwidth="0" src="" style="visibility:hidden;"></iframe></div>';
            $.fancybox(content,
            {
                'autoScale': false,
                'transitionIn': 'none',
                'transitionOut': 'none',
                'padding': 0,
                onComplete: function () {
                    
                }
            });

            popup = $("#fancybox-content");
            popup.children().css("overflow", "hidden");

            popup.iframe = popup.find('iframe');
            popup.loader = popup.find('.carbon-loader-overlay');
            /*args.iframe.bind('load', function () {
                boxy.title.html(boxy.iframe.contents().find("title").html());
            });*/
            popup.iframe.one('load', function () {
                popup.loader.css('display', 'none');
                popup.iframe.css('visibility', 'visible');
            });
            popup.iframe.attr('src', args.Url);
            popup.invokePostback = args.InvokeViewModelChanged;
        };

        manager.ClosePopup = function (window, invokePostback) {
            // to work in Opera
            setTimeout(function() {
                if (invokePostback)
                    popup.invokePostback();
                $.fancybox.close();
            }, 0);
        };

        PopupManagerInstance = manager;
    };

    Type.registerNamespace("Carbon.Web.Forms.jQueryForms");
    $.extend(window.Carbon.Web.Forms.jQueryForms, ui);

    Carbon.Popup.Factories = {
        OpenPopup: function (ctx) {
            ui.GetRootPopupManager().OpenPopup(ctx);
        },
        ParentDocument: function () {
            return parent.document;
        },
        ClosePopup: function (invokePostback) {
            var rootManager = ui.GetRootPopupManager();
            rootManager.ClosePopup(window, invokePostback);
        }
    };

    PopupManager();

    if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
})(jQuery);